/*******************************************************************************
 * FilePath    : /MS2583/MS2583.C
 * Version     : 1.0
 * Brief       :
 * Author      : AndrewHu
 * Company     : Shanghai MacroGiga Electronics CO.,Ltd
 * Email       : Hubinbo@macrogiga.com
 * Date        : 2021-03-03 17:08:51
 * LastEditors : AndrewHu
 * LastEditTime: 2022-06-23 11:50:03
 * Description :
 ******************************************************************************/
/*******************************************************************************
 *    Copyright (c) 2020 Macrogiga Electronics Co., Ltd.
 *
 *    Permission is hereby granted, free of charge, to any person
 *    obtaining a copy of this software and associated documentation
 *    files (the 'Software'), to deal in the Software without
 *    restriction, including without limitation the rights to use, copy,
 *    modify, merge, publish, distribute, sublicense, and/or sell copies
 *    of the Software, and to permit persons to whom the Software is
 *    furnished to do so, subject to the following conditions:
 *
 *    The above copyright notice and this permission notice shall be
 *    included in all copies or substantial portions of the Software.
 *
 *    THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
 *    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 *    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 *    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 *    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 *    DEALINGS IN THE SOFTWARE.
 ******************************************************************************/
/***************************************************************
						 ┌──────────┐
				 PA7/X1 ─│1 ●     16│─ VDD
				 PA6/X2 ─│2       15│─ PB7/CIN5-/PG1PWM
	   PA5/PRST#/PG2PWM ─│3       14│─ PB5/INT0A/PG0PWM
PA3/TM2PWM/CIN0-/PG2PWM ─│4       13│─ PB4/TM2PWM/PG0PWM
 PA4/CIN1-/INT1A/PG1PWM ─│5       12│─ PB6/CIN4-/PG1PWM
	 PA0/CO/PG0PWM/INT0 ─│6       11│─ VDD(MG223)
					 XO ─│7       10│─ GND
					 XI ─│8        9│─ ANT
						 └──────────┘
						 MS1581-16pin
***************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "extern.h"

/*Package define -------------------------------------------------------------*/
//              ?P  VDD PA0 PA3 PA4 PA5 PA6 PA7 GND MASK1   MASK2   shift
.writer package 16, 16, 6, 4, 5, 3, 2, 1, 10, 0x003f, 0x005f, 0;
/* Private typedef -----------------------------------------------------------*/
typedef BYTE u8;   // 8bit
typedef WORD u16;  // 16bit
typedef EWORD u24; // 24bit
typedef DWORD u32; // 32bit
/* Private define ------------------------------------------------------------*/
#define true 1
#define false 0
#define f_stat_z flag .0
#define f_stat_c flag .1
/* GPIO define ---------------------------------------------------------------*/
#define LED_SUPPORT true

#define key_In01_bit PA .7
#define key_In02_bit PA .6
// #if (LED_SUPPORT == true)
#define led_bit PA .5
// #else
#define key_In03_bit PA .5
// #endif
#define key_In04_bit PA .3
#define key_In05_bit PA .4
#define key_In06_bit PA .0

#define key_Out01_bit PB .6
#define key_Out02_bit PB .4
#define key_Out03_bit PB .5
#define key_Out04_bit PB .7

#define spi_moi PB .0
#define spi_clk PB .1
#define spi_csn PB .2
#define spi_rst PB .3
/* KEY VALUE -----------------------------------------------------------------*/
#define KEY_PA7_PB6 0x01
#define KEY_PA6_PB6 0x02
#define KEY_PA5_PB6 0x03
#define KEY_PA3_PB6 0x04
#define KEY_PA4_PB6 0x05
#define KEY_PA0_PB6 0x06
#define KEY_PA7_PB4 0x07
#define KEY_PA6_PB4 0x08
#define KEY_PA5_PB4 0x09
#define KEY_PA3_PB4 0x0A
#define KEY_PA4_PB4 0x0B
#define KEY_PA0_PB4 0x0C
#define KEY_PA7_PB5 0x0D
#define KEY_PA6_PB5 0x0E
#define KEY_PA5_PB5 0x0F
#define KEY_PA3_PB5 0x10
#define KEY_PA4_PB5 0x11
#define KEY_PA0_PB5 0x12
#define KEY_PA7_PB7 0x13
#define KEY_PA6_PB7 0x14
#define KEY_PA5_PB7 0x15
#define KEY_PA3_PB7 0x16
#define KEY_PA4_PB7 0x17
#define KEY_PA0_PB7 0x18
#define KEY_PA7_GND 0x19
#define KEY_PA6_GND 0x1A
#define KEY_PA5_GND 0x1B
#define KEY_PA3_GND 0x1C
#define KEY_PA4_GND 0x1D
#define KEY_PA0_GND 0x1E
/* BLE define ----------------------------------------------------------------*/
#define RfTest_Disable 0
#define RfTest_Carrier 1
#define RfTest_Prbs9 2
#define RfTest RfTest_Disable

#define TxData_ADV 0 //单广播
#define TxData_LED 1 //灯控遥控器
#define TxData_KEY 2 //按键遥控器（设备名显示）
#define TxData TxData_KEY
/*---------------------------------------------------------------------------*/

#define LEN_BLE_ADDR 6
// BLE ADV_data, maxlen=31
#define LEN_DATA 31

/* set BLE TX power */
#define BLE_TX_POWER_3dbm 10
#define BLE_TX_POWER0dbm 18
#define BLE_TX_POWER1dbm 21
#define BLE_TX_POWER2dbm 25
#define BLE_TX_POWER3dbm 30
#define BLE_TX_POWER3P5dbm 31
#define BLE_TX_POWER_DEF BLE_TX_POWER3dbm

// #define CNT_RC_1MS 32UL
// #define CNT_ADV_INTERV 100 //广播间隔,ms
// #define CNT_ADV_INTERV_Data (CNT_RC_1MS * CNT_ADV_INTERV)
// #define CNT_ADV_INTERV_H 0x00
// #define CNT_ADV_INTERV_M 0x00
// #define CNT_ADV_INTERV_L 0xa0 // 32*5MS = 0xa0
// #define CNT_ADV_INTERV_H 0x00
// #define CNT_ADV_INTERV_M 0x00
// #define CNT_ADV_INTERV_L 0xc0 // 32*6MS = 0xc0
#define CNT_ADV_INTERV_H 0x00
#define CNT_ADV_INTERV_M 0x01
#define CNT_ADV_INTERV_L 0x00 // 32*8MS = 0x100
// #define CNT_ADV_INTERV_H 0x00
// #define CNT_ADV_INTERV_M 0x01
// #define CNT_ADV_INTERV_L 0x40 // 32*10MS = 0x640
// #define CNT_ADV_INTERV_H 0x00
// #define CNT_ADV_INTERV_M 0x03
// #define CNT_ADV_INTERV_L 0xC0 // 32*30MS = 0x3C0
// #define CNT_ADV_INTERV_H 0x00
// #define CNT_ADV_INTERV_M 0x06
// #define CNT_ADV_INTERV_L 0x40 // 32*50MS = 0x640
// #define CNT_ADV_INTERV_H 0x00
// #define CNT_ADV_INTERV_M 0x0c
// #define CNT_ADV_INTERV_L 0x80 // 32*100MS = 0xC80

#define POWER_SAVE_SLEEP 0
#define POWER_SAVE_STANDBY 1
#define POWER_SAVE_OPT 1

// INT
//#define INT_TYPE_WAKEUP   	0x20
//#define INT_TYPE_SLEEP    	0x10

/*-------------------------------BLE register---------------------------------*/
// TX Data Payload maxLen 31 Bytes
#define R_TX_PAYLOAD 0xE0
#define W_TX_PAYLOAD 0xE1

#define CONFIG 0x00
#define CONT_TEST_MODE 0x01
#define WAKEUP_NOW 0x02
#define ADV_PKT_CFG 0x03
#define BLE_ADVA 0x04
#define ADV_INTERV_RC_CFG 0x13
#define BASEBAND_CFG 0x14
#define XO_PD_EN 0x18
// Chip ok
#define CHIP_READY 0x18
#define INT_MASK 0x1C
#define INT_FLAG 0x1D
#define IC_VER 0x1E
#define RESET_BB 0x21
#define XO_WAIT 0x25
#define PA_CFG 0x2F
#define BG_CAL 0x33
#define XO_SET 0x34
#define ABUS_ACC 0x37
/*-------------------------------BLE register  End----------------------------*/
/*
15:8:	Pdu length
7:0:	Pdu type
*/
#define ADV_IND 0
#define ADV_DIRECT_IND 1
#define ADV_NONCONN_IND 2
#define ADV_SCAN_REQ 3
#define ADV_SCAN_RSP 4
#define ADV_CONN_REQ 5
#define ADV_SCAN_IND 6

// 0x40: Random, 0x00: Public
#define ADV_TXADD_PUBLIC 0x00
#define ADV_TXADD_RANDOM 0x40

// Nordic SDK GAP  AD_TYPE
#define BLE_GAP_AD_TYPE_FLAGS 0x01								/**< Flags for discoverability. */
#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE 0x02	/**< Partial list of 16 bit service UUIDs. */
#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE 0x03		/**< Complete list of 16 bit service UUIDs. */
#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_MORE_AVAILABLE 0x04	/**< Partial list of 32 bit service UUIDs. */
#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_COMPLETE 0x05		/**< Complete list of 32 bit service UUIDs. */
#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE 0x06 /**< Partial list of 128 bit service UUIDs. */
#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE 0x07		/**< Complete list of 128 bit service UUIDs. */
#define BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME 0x08					/**< Short local device name. */
#define BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME 0x09				/**< Complete local device name. */
#define BLE_GAP_AD_TYPE_TX_POWER_LEVEL 0x0A						/**< Transmit power level. */
#define BLE_GAP_AD_TYPE_CLASS_OF_DEVICE 0x0D					/**< Class of device. */
#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C 0x0E				/**< Simple Pairing Hash C. */
#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R 0x0F		/**< Simple Pairing Randomizer R. */
#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE 0x10			/**< Security Manager TK Value. */
#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS 0x11			/**< Security Manager Out Of Band Flags. */
#define BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE 0x12	/**< Slave Connection Interval Range. */
#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT 0x14		/**< List of 16-bit Service Solicitation UUIDs. */
#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT 0x15		/**< List of 128-bit Service Solicitation UUIDs. */
#define BLE_GAP_AD_TYPE_SERVICE_DATA 0x16						/**< Service Data - 16-bit UUID. */
#define BLE_GAP_AD_TYPE_PUBLIC_TARGET_ADDRESS 0x17				/**< Public Target Address. */
#define BLE_GAP_AD_TYPE_RANDOM_TARGET_ADDRESS 0x18				/**< Random Target Address. */
#define BLE_GAP_AD_TYPE_APPEARANCE 0x19							/**< Appearance. */
#define BLE_GAP_AD_TYPE_ADVERTISING_INTERVAL 0x1A				/**< Advertising Interval. */
#define BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS 0x1B		/**< LE Bluetooth Device Address. */
#define BLE_GAP_AD_TYPE_LE_ROLE 0x1C							/**< LE Role. */
#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C256 0x1D			/**< Simple Pairing Hash C-256. */
#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R256 0x1E		/**< Simple Pairing Randomizer R-256. */
#define BLE_GAP_AD_TYPE_SERVICE_DATA_32BIT_UUID 0x20			/**< Service Data - 32-bit UUID. */
#define BLE_GAP_AD_TYPE_SERVICE_DATA_128BIT_UUID 0x21			/**< Service Data - 128-bit UUID. */
#define BLE_GAP_AD_TYPE_3D_INFORMATION_DATA 0x3D				/**< 3D Information Data. */
#define BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA 0xFF			/**< Manufacturer Specific Data. */

#define GAP_ADTYPE_FLAGS_LIMITED 0x01			  //!< Discovery Mode: LE Limited Discoverable Mode
#define GAP_ADTYPE_FLAGS_GENERAL 0x02			  //!< Discovery Mode: LE General Discoverable Mode
#define GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED 0x04 //!< Discovery Mode: BR/EDR Not Supported
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/*******************************************************************************
注意：以下两行请勿更改
1、Fun_Clr_RAM()函数要预留系统占用字节，否则会一直复位，例如堆栈空间，结合仿真器视图检查
2、TM16中断时间可以自己修改，但是sys_delay_set(主循环时序累计)最好维持10ms以内
*******************************************************************************/
.RAMADR 0x00;
u16 point;
//------------------------------------------------------------------------------
u8 sys_flag;
u8 sys_delay;
u8 sys_sleep_delay;
u8 sys_temp_8bit1;
u8 sys_temp_8bit2;
u8 sys_temp_8bit3;
// u16 sys_temp_16bit;
// u32 sys_temp_32bit;
#define f_sys_tmr sys_flag .7		  //计时中断
#define f_sys_2ms sys_flag .6		  //计时10ms
#define f_sys_power sys_flag .5		  //第一次上电
#define f_sys_ble_en sys_flag .4	  // BLE工作使能
#define f_sys_ble_standby sys_flag .3 //低功耗

#define sys_delay_set 0x04
#define sys_sleep_delay_set 0x14
// BLE--------------------------------------------------------------------------
u8 SpiData[33] = {0x00};	  // 31-length,32-reg
u8 &SpiDataLen = SpiData[31]; //确定是否是我们的产品（是否有更换24C02
u8 &SpiAddr = SpiData[32];	  //

// u8 DataArry[LEN_DATA] = {
// 	//广播包
// 	2, BLE_GAP_AD_TYPE_FLAGS, GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,													 //
// 	19, BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA, 'M', 'G', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, //
// 	7, BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME, 'M', 'S', '2', '5', '8', '3',											 //
// };

u8 ver;		 //芯片版本号
u8 KeyValue; //按键发码，bit8:0-松开，1-按下
u8 AddNum;	 //累加序号
u8 Addr[6];	 // Mac地址后3位

// #define BleTxDelay_SET 0x4b // 2.048MS*50=102.4ms
#define BleTxDelay_SET 150 // 2.048MS*50=100mS
// #define BleTxDelay_SET 0xfa // 2.048MS*250=512mS
u8 BleTxDelay;	 //发码延时，每次按键按下或松开，延时发送1秒
u8 BleRestDelay; //
// KEY--------------------------------------------------------------------------
#define KEY_READ 00000110b	 //读取按键状态
#define KEY_STATUS_ELES 0xff //多按键按下
#define KEY_STATUS_UP 0x00	 //
u8 key_status;				 //按键状态
u8 key_status_old;			 //按键状态1，判断连按
u8 key_status_now;			 //按键状态2
u8 key_status_new;			 //按键状态3，当前状态

#define KEY_DELAY_SHORT_HSET 0x06 //松开去抖时间
#define KEY_DELAY_SHORT_LSET 0x03 //按下去抖时间
#define KEY_DELAY_TIMES_SET 0x52  //连按判断
#define KEY_DELAY_LONG_SET 0xa4	  //长按，2000/(6*2.024)
u8 key_delay;					  //按键去抖
u8 key_Ldelay;					  //长按、连按判断

u8 key_times; //连按次数
#define KEY_FLAG_UP 0x00
#define KEY_FLAG_DOWN 0x01
#define KEY_FLAG_LONG 0x04
u8 key_flag; // 1-按键按下，0-松开，4-长按

#if (RfTest != RfTest_Disable)
u8 chan;
#endif
/* Private function ----------------------------------------------------------*/
void Delay_ms(void);
void Delay_Nop(void);
void SPI_Write_Byte(void);
void SPI_Read_Byte(void);
void SPI_Write_Reg(void);
void SPI_Read_Reg(void);
void SPI_Write_Buf(void);
void SPI_Read_Buf(void);
void Sleep_Delay_Init(void);
/* extern --------------------------------------------------------------------*/
/*******************************************************************************
 * Function    : Delay_ms
 * Brief       : 延时
 * Parameter   :
 * Returns     :
 * Date        : 2020-04-03 17:14:47
 * Description : unit 512us
 ******************************************************************************/
void Delay_ms(void)
{
	f_sys_tmr = false;
	while (sys_temp_8bit1)
	{
		if (f_sys_tmr == true)
		{
			f_sys_tmr = false;
			sys_temp_8bit1--;
		}
		.Wdreset;
	}
}
/*******************************************************************************
 * Function    : Delay_Nop
 * Brief       : 延时
 * Parameter   :
 * Returns     :
 * Date        : 2020-04-03 17:14:47
 * Description :
 ******************************************************************************/
void Delay_Nop(void)
{
	NOP;
	NOP;
	NOP;
	NOP;
}
/*******************************************************************************
 * Function    : SPI_Write_Byte
 * Brief       : SPI写入
 * Parameter   :
 * Returns     :
 * Date        : 2020-04-03 17:14:47
 * Description :
 ******************************************************************************/
void SPI_Write_Byte(void)
{
	// spi_moi = false;
	// spi_clk = false;

	sys_temp_8bit2 = A;
	sys_temp_8bit1 = 8;
	do
	{
		// Delay_Nop();
		if (sys_temp_8bit2 .7 == true)
			spi_moi = true;
		else
			spi_moi = false;
		sys_temp_8bit2 <<= 1;
		// Delay_Nop();
		spi_clk = true;
		sys_temp_8bit1--;
		// Delay_Nop();
		spi_clk = false;
	} while (sys_temp_8bit1 != 0);
	// spi_moi = false;
}
/*******************************************************************************
 * Function    : SPI_Read_Byte
 * Brief       : SPI读取
 * Parameter   :
 * Returns     : SpiData[0]
 * Date        : 2020-04-03 17:14:47
 * Description :
 ******************************************************************************/
void SPI_Read_Byte(void)
{
	// spi_moi = false;
	// spi_clk = false;
	// $ spi_moi In;

	PBC &= 11111110b; // 输入输出控制，0-输入，1-输出

	sys_temp_8bit2 = 0;
	sys_temp_8bit1 = 8;
	do
	{
		// Delay_Nop();
		sys_temp_8bit2 <<= 1;
		spi_clk = true;
		// Delay_Nop();
		if (spi_moi == true)
			sys_temp_8bit2++;

		spi_clk = false;
		sys_temp_8bit1--;
	} while (sys_temp_8bit1 != 0);

	// $ spi_moi Out, Low;
	PBC |= 00000001b; // 输入输出控制，0-输入，1-输出
	// spi_moi = false;

	A = sys_temp_8bit2;
}
/*******************************************************************************
 * Function    : SPI_Write_Reg
 * Brief       : 写寄存器
 * Parameter   :
 * Returns     :
 * Date        : 2020-04-03 17:14:47
 * Description :
 ******************************************************************************/
void SPI_Write_Reg(void)
{
	spi_csn = false;

	A = SpiAddr | 0x40;
	SPI_Write_Byte();
	// Delay_Nop();
	// Delay_Nop();
	A = SpiData[0];
	SPI_Write_Byte();
	spi_csn = true;
	// Delay_Nop();
	// Delay_Nop();
	// Delay_Nop();

	// GOTO SPI_Read_Reg; // TEST
}
/*******************************************************************************
 * Function    : SPI_Read_Reg
 * Brief       : 读寄存器
 * Parameter   :
 * Returns     : sys_temp_8bit1
 * Date        : 2020-04-03 17:14:47
 * Description :
 ******************************************************************************/
void SPI_Read_Reg(void)
{
	spi_csn = false;

	A = SpiAddr;
	SPI_Write_Byte();
	// Delay_Nop();
	// Delay_Nop();

	SPI_Read_Byte();
	SpiData[0] = A;
	spi_csn = true;
	// Delay_Nop();
	// Delay_Nop();
	// Delay_Nop();
}
/*******************************************************************************
 * Function    : SPI_Write_Buf
 * Brief       : 写寄存器
 * Parameter   :
 * Returns     :
 * Date        : 2020-04-03 17:14:47
 * Description :
 ******************************************************************************/
void SPI_Write_Buf(void)
{
	spi_csn = false;

	A = SpiAddr | 0x40;
	SPI_Write_Byte();

	point = SpiData;
	sys_temp_8bit3 = SpiDataLen;
	while (sys_temp_8bit3 != 0)
	{
		// Delay_Nop();
		// Delay_Nop();
		A = *point;
		SPI_Write_Byte();
		point++;
		sys_temp_8bit3--;
	}

	spi_csn = true;
	// Delay_Nop();
	// Delay_Nop();
	// Delay_Nop();

	// GOTO SPI_Read_Buf; // TEST
}
/*******************************************************************************
 * Function    : SPI_Read_Buf
 * Brief       : 读寄存器
 * Parameter   :
 * Returns     :
 * Date        : 2020-04-03 17:14:47
 * Description :
 ******************************************************************************/
void SPI_Read_Buf(void)
{
	spi_csn = false;

	A = SpiAddr;
	SPI_Write_Byte();

	point = SpiData;
	sys_temp_8bit3 = SpiDataLen;
	while (sys_temp_8bit3 != 0)
	{
		// Delay_Nop();
		// Delay_Nop();
		SPI_Read_Byte();
		*point = A;
		point++;
		sys_temp_8bit3--;
	}

	spi_csn = true;
	// Delay_Nop();
	// Delay_Nop();
	// Delay_Nop();
}
/*******************************************************************************
 * Function    : BLE_TX_Power
 * Brief       : 设置发射功率
 * Parameter   :
 * Returns     :
 * Date        : 2020-04-03 17:14:47
 * Description :
 ******************************************************************************/
void BLE_TX_Power(void)
{
	SpiData[0] = 0x08;
	SpiData[1] = BLE_TX_POWER_DEF; // BLE_TX_POWER; //0~1F
	SpiAddr = PA_CFG;
	SpiDataLen = 0x02;
	SPI_Write_Buf();
}
/*******************************************************************************
 * Function    : BLE_Adv_Auto_Interv
 * Brief       : 设置发包间隔
 * Parameter   : sys_temp_32bit
 * Returns     :
 * Date        : 2020-04-03 17:14:47
 * Description :
 ******************************************************************************/
void BLE_Adv_Auto_Interv(void)
{
	// SpiData[0] = sys_temp_32bit $ 0;
	// SpiData[1] = sys_temp_32bit $ 1;
	// SpiData[3] = sys_temp_32bit $ 2;

	SpiData[0] = CNT_ADV_INTERV_L;
	SpiData[1] = CNT_ADV_INTERV_M;
	SpiData[2] = CNT_ADV_INTERV_H;
	SpiData[3] = 0x01;
	SpiAddr = ADV_INTERV_RC_CFG;
	SpiDataLen = 0x04;
	SPI_Write_Buf();
}
/*******************************************************************************
 * Function    : BLE_Mode_PwrUp
 * Brief       : 上电
 * Parameter   :
 * Returns     :
 * Date        : 2020-04-03 17:14:47
 * Description :
 ******************************************************************************/
void BLE_Mode_PwrUp(void)
{
	SpiData[0] = 0x01;
	SpiAddr = 0x3e;
	SPI_Write_Reg();
}
/*******************************************************************************
 * Function    : BLE_Stop_Adv
 * Brief       : 停止广播
 * Parameter   :
 * Returns     :
 * Date        : 2020-04-03 17:14:47
 * Description :
 ******************************************************************************/
void BLE_Stop_Adv(void)
{
	f_sys_ble_en = false;
	SpiData[0] = 0x06; // SLP_XO=4, STOP=2，停止广播
	SpiAddr = BASEBAND_CFG;
	SPI_Write_Reg();
}
/*******************************************************************************
 * Function    : BLE_Mode_Sleep
 * Brief       : 休眠
 * Parameter   :
 * Returns     :
 * Date        : 2020-04-03 17:14:47
 * Description :
 ******************************************************************************/
void BLE_Mode_Sleep(void)
{
	BLE_Stop_Adv(); //停止广播

	SpiData[0] = 0x00;
	SpiAddr = XO_PD_EN;
	SPI_Write_Reg();

	SpiData[0] = 0x01;
	SpiAddr = XO_PD_EN;
	SPI_Write_Reg();

	SpiData[0] = 0x05;
	SpiAddr = 0x3e;
	SPI_Write_Reg();
}
/*******************************************************************************
 * Function    : BLE_Mode_Standby
 * Brief       : 休眠
 * Parameter   :
 * Returns     :
 * Date        : 2020-04-03 17:14:47
 * Description :
 ******************************************************************************/
void BLE_Mode_Standby(void) // standby(deepsleep)
{
	BLE_Stop_Adv(); //停止广播

	SpiData[0] = 0x00;
	SpiAddr = XO_PD_EN;
	SPI_Write_Reg();

	SpiData[0] = 0x01;
	SpiAddr = XO_PD_EN;
	SPI_Write_Reg();

	SpiData[0] = 0x40;
	SpiAddr = 0x23;
	SPI_Write_Reg();
	// O: irq = H, miso = L
	// I: csn/sck/mosi PU
	f_sys_ble_standby = true;
	BleRestDelay = 0x00;
}
/*******************************************************************************
 * Function    :
 * Brief       : 复用函数
 * Parameter   :
 * Returns     :
 * Date        : 2020-04-03 17:14:47
 * Description :
 ******************************************************************************/
void SPI_Read_BG_CAL(void)
{
	SpiAddr = BG_CAL;
	SpiDataLen = 4;
	SPI_Read_Buf();
}
void SPI_ClearFlag(void)
{
	SpiData[0] = 0x01;
	SpiAddr = RESET_BB;
	SPI_Write_Reg();

	SpiData[0] = 0x00;
	SpiAddr = RESET_BB;
	SPI_Write_Reg();
}
/*******************************************************************************
 * Function    : patch
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-04-03 17:14:47
 * Description :
 ******************************************************************************/
void patch(void)
{
	SpiData[0] = 0x31;
	SpiData[1] = 0x08;
	SpiData[2] = A; // 0x08
	SpiData[3] = A; // 0x08
	SpiAddr = 0x3B;
	SpiDataLen = 0x04;
	SPI_Write_Buf();

	SpiData[0] = 0xa0;
	SpiData[1] = 0x20;
	SpiAddr = BG_CAL;
	SpiDataLen = 0x02;
	SPI_Write_Buf();

	SpiData[0] = 0x03;
	SpiData[1] = 0x02;
	SpiAddr = XO_SET;
	SpiDataLen = 0x02;
	SPI_Write_Buf();

	SpiData[0] = 0x40;
	SpiData[1] = 0x08;
	SpiData[2] = 0x03;
	SpiData[3] = 0x55;
	SpiAddr = ABUS_ACC;
	SpiDataLen = 0x04;
	SPI_Write_Buf();

	SpiData[0] = 0x34;
	SpiData[1] = 0x3c;
	SpiData[2] = 0x33;
	SpiData[3] = 0x55;
	SpiAddr = ABUS_ACC;
	SpiDataLen = 0x04;
	SPI_Write_Buf();

	if (0x42 < ver)
	{
		SpiData[0] = 0x25;
		SpiData[1] = 0xf4;
		SpiData[2] = 0x33;
		SpiData[3] = 0x55;
		SpiAddr = ABUS_ACC;
		SpiDataLen = 0x04;
		SPI_Write_Buf();

		SpiData[0] = 0xb1;
		SpiData[1] = 0x14;
		SpiData[2] = 0x33;
		SpiData[3] = 0x55;
		SpiAddr = ABUS_ACC;
		SpiDataLen = 0x04;
		SPI_Write_Buf();

		SpiData[0] = 0xc0;
		SpiData[1] = 0x0c;
		SpiData[2] = 0x33;
		SpiData[3] = 0x55;
		SpiAddr = ABUS_ACC;
		SpiDataLen = 0x04;
		SPI_Write_Buf();

		SpiData[0] = 0xc1;
		SpiData[1] = 0x73;
		SpiData[2] = 0x33;
		SpiData[3] = 0x55;
		SpiAddr = ABUS_ACC;
		SpiDataLen = 0x04;
		SPI_Write_Buf();

		SpiData[0] = 0xc4;
		SpiData[1] = 0xe4;
		SpiData[2] = 0x33;
		SpiData[3] = 0x55;
		SpiAddr = ABUS_ACC;
		SpiDataLen = 0x04;
		SPI_Write_Buf();

		SpiData[0] = 0xc5;
		SpiData[1] = 0x2c;
		SpiData[2] = 0x33;
		SpiData[3] = 0x55;
		SpiAddr = ABUS_ACC;
		SpiDataLen = 0x04;
		SPI_Write_Buf();

		SpiData[0] = 0xc7;
		SpiData[1] = 0x60;
		SpiData[2] = 0x33;
		SpiData[3] = 0x55;
		SpiAddr = ABUS_ACC;
		SpiDataLen = 0x04;
		SPI_Write_Buf();

		// SpiAddr = BG_CAL;
		// SpiDataLen = 4;
		// SPI_Read_Buf();
		SPI_Read_BG_CAL();

		if (SpiData[3] .5 == true)
		{
			SpiData[3] &= 0x1f;
			SpiData[3] <<= 2;
			SpiData[1] = SpiData[3] | 0x80;
		}
		else
			SpiData[1] = 0xb0;

		SpiData[0] = 0xb0;
		SpiData[2] = 0x33;
		SpiData[3] = 0x55;
		SpiAddr = ABUS_ACC;
		SpiDataLen = 0x04;
		SPI_Write_Buf();
	}
	else if (0x41 == ver)
	{
		SpiData[0] = 0xc0;
		SpiData[1] = 0x0e;
		SpiData[2] = 0x03;
		SpiData[3] = 0x55;
		SpiAddr = ABUS_ACC;
		SpiDataLen = 0x04;
		SPI_Write_Buf();

		SpiData[0] = 0xc1;
		SpiData[1] = 0x44;
		SpiData[2] = 0x03;
		SpiData[3] = 0x55;
		SpiAddr = ABUS_ACC;
		SpiDataLen = 0x04;
		SPI_Write_Buf();

		SpiData[0] = 0xc4;
		SpiData[1] = 0xe0;
		SpiData[2] = 0x03;
		SpiData[3] = 0x55;
		SpiAddr = ABUS_ACC;
		SpiDataLen = 0x04;
		SPI_Write_Buf();

		// SpiAddr = BG_CAL;
		// SpiDataLen = 4;
		// SPI_Read_Buf();
		SPI_Read_BG_CAL();

		if (SpiData[3] .5 == true)
		{
			SpiData[3] &= 0x1f;
			SpiData[3] <<= 2;
			SpiData[1] = SpiData[3] | 0x83;
		}
		else
			SpiData[1] = 0xCf;
		// SpiData[1] = 0xff;

		SpiData[0] = 0xb0;
		SpiData[2] = 0x03;
		SpiData[3] = 0x55;
		SpiAddr = ABUS_ACC;
		SpiDataLen = 0x04;
		SPI_Write_Buf();

		SpiData[0] = 0xb1;
		SpiData[1] = 0x14;
		SpiData[2] = 0x03;
		SpiData[3] = 0x55;
		SpiAddr = ABUS_ACC;
		SpiDataLen = 0x04;
		SPI_Write_Buf();
	}
}
/*******************************************************************************
 * Function    : BLE_RESET
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2021-04-14 15:00:17
 * Description :
 ******************************************************************************/
void BLE_RESET(void)
{
	spi_rst = false;
	sys_temp_8bit1 = 0x04;
	// sys_temp_8bit1 = 0x0a;
	Delay_ms(); // unit 512us
	spi_rst = true;
	// sys_temp_8bit1 = 0x20;
	sys_temp_8bit1 = 0x35;
	// sys_temp_8bit1 = 0x64;
	Delay_ms(); // unit 512us
}
/*******************************************************************************
 * Function    : BLE_Init
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-04-03 17:14:47
 * Description :
 ******************************************************************************/
void BLE_Init(void)
{
	BLE_Mode_PwrUp();

	while (1)
	{
		SpiData[0] = 0x08;
		SpiAddr = CONT_TEST_MODE;
		SPI_Write_Reg();

		SpiAddr = CHIP_READY;
		SPI_Read_Reg();

		if (SpiData[0] == 0xff)
			continue;
		else
		{
			SpiData[0] &= 0x04;
			if (SpiData[0] != 0x04)
				continue;
			else
				break;
		}
	}

	// SpiData[0] = 0x01;
	// SpiAddr = RESET_BB;
	// SPI_Write_Reg();

	// SpiData[0] = 0x00;
	// SpiAddr = RESET_BB;
	// SPI_Write_Reg();
	SPI_ClearFlag();

	SpiData[0] = 0xDC;
	SpiAddr = RESET_BB;
	SPI_Write_Reg();

	do
	{
		SpiAddr = RESET_BB;
		SPI_Read_Reg();
		SpiData[0] &= 0x02;
	} while (SpiData[0] != 0x02);

	// SpiData[0] = 0x01;
	// SpiAddr = RESET_BB;
	// SPI_Write_Reg();

	// SpiData[0] = 0x00;
	// SpiAddr = RESET_BB;
	// SPI_Write_Reg();
	SPI_ClearFlag();

	SpiData[0] = 0x01;
	SpiAddr = XO_PD_EN;
	SPI_Write_Reg();

#if 1 // xo_pd_wait_adjust
	SpiData[0] = 0xdb;
	SpiData[1] = 0x05;
	SpiData[2] = 0x29;
	SpiData[3] = 0x1e;
	SpiData[4] = 0x30;
	SpiAddr = XO_WAIT;
	SpiDataLen = 0x05;
	SPI_Write_Buf();
#endif

	SpiAddr = IC_VER;
	SPI_Read_Reg();
	ver = SpiData[0];
	patch();

	SpiAddr = 0x16;
	SpiDataLen = 0x06;
	SPI_Read_Buf(); //读取MAC地址

	Addr[0] = SpiData[0];
	Addr[1] = SpiData[1];
	Addr[2] = SpiData[2];
	Addr[3] = SpiData[3];
	Addr[4] = SpiData[4];
	Addr[5] = SpiData[5];

	// SpiData[5] = 0xc0;
	// SpiData[4] = 0x00;
	// SpiData[3] = 0x00;
	// SpiData[2] = 0x00;
	// SpiData[1] = 0x00;
	// SpiData[0] = 0x02;
	// SpiAddr = 0x16;
	// SpiDataLen = 0x06;
	// SPI_Write_Buf(); //写入地址

	BLE_TX_Power();

	sys_temp_8bit1 = 0x02;
	Delay_ms(); // unit 512us

	SpiData[0] = 0x87;
	SpiAddr = CONFIG;
	SPI_Write_Reg(); // PREAMBLE_LEN_AUTO | SCRAMBLE_ON | CRC_EN | POWER_UP

	SpiData[0] = 0x6F;
	SpiAddr = INT_MASK;
	SPI_Write_Reg(); // sleep int
}
/*******************************************************************************
 * Function    : BLE_Tx_Enable
 * Brief       : 发包使能
 * Parameter   :
 * Returns     :
 * Date        : 2020-04-03 17:14:47
 * Description :
 ******************************************************************************/
void BLE_Tx_Enable(void)
{
	BLE_Mode_PwrUp();

	// sys_temp_32bit = CNT_ADV_INTERV_Data;
	BLE_Adv_Auto_Interv();

	//设置广播内容
#if (TxData == TxData_LED)
	// Structure 1
	SpiData[0] = 0x5e;
	SpiData[1] = 0x01;
	SpiData[2] = KeyValue;
	// SpiData[2] = 0x08;
	SpiData[3] = key_flag;
	// SpiData[4] = key_times;
	SpiData[4] = AddNum;
	SpiData[5] = Addr[2];
	SpiData[6] = Addr[1];
	SpiData[7] = Addr[0];
	// SpiData[5] = 0x14;
	// SpiData[6] = 0x1e;
	// SpiData[7] = 0x11;
	SpiData[8] = 0xef;
	SpiAddr = W_TX_PAYLOAD;
	SpiDataLen = 9;
	SPI_Write_Buf();

	// PDU TYPE: 2  non-connectable undirected advertising . tx add:random address
	// set BLT PDU length:adv_data+6 mac adress.
	SpiData[0] = 0x08;
	SpiData[1] = ADV_NONCONN_IND | ADV_TXADD_RANDOM;
	// SpiData[1] = ADV_IND | ADV_TXADD_PUBLIC;
	SpiData[2] = 9 + LEN_BLE_ADDR;
	SpiAddr = ADV_PKT_CFG;
	SpiDataLen = 3;
	SPI_Write_Buf();
#elif (TxData == TxData_KEY)
	// Structure 1
	SpiData[0] = 2;
	SpiData[1] = BLE_GAP_AD_TYPE_FLAGS;
	SpiData[2] = GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED;
	// Structure 2
	SpiData[3] = 12;
	SpiData[4] = BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA;
	SpiData[5] = 0x9c;
	SpiData[6] = 0x05; // MacroGiga
	SpiData[7] = Addr[5];
	SpiData[8] = Addr[4];
	SpiData[9] = Addr[3];
	SpiData[10] = Addr[2];
	SpiData[11] = Addr[1];
	SpiData[12] = Addr[0];
	SpiData[13] = KeyValue;
	SpiData[14] = key_flag;
	SpiData[15] = AddNum;
	// Structure 3
	SpiData[16] = 14;
	SpiData[17] = BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME;
	SpiData[18] = 'M';
	SpiData[19] = 'S';
	SpiData[20] = '2';
	SpiData[21] = '5';
	SpiData[22] = '8';
	SpiData[23] = '3';
	SpiData[24] = '-';
	SpiData[25] = 'K';
	SpiData[26] = 'E';
	SpiData[27] = 'Y';

	//显示按键码
	SpiData[28] = KeyValue >> 4;
	if (SpiData[28] > 9)
		SpiData[28] += ('A' - 10);
	else
		SpiData[28] += '0';

	SpiData[29] = KeyValue & 0x0f;
	if (SpiData[29] > 9)
		SpiData[29] += ('A' - 10);
	else
		SpiData[29] += '0';

	//按键状态
	if (key_flag == 0x00)
		SpiData[30] = 'U'; // UP松开
	else if (key_flag == 0x01)
		SpiData[30] = 'D'; // DOWN按下
	else if (key_flag == 0x04)
		SpiData[30] = 'L'; // LONG长按
	else
		SpiData[30] = '?'; //未知

	SpiAddr = W_TX_PAYLOAD;
	SpiDataLen = 31;
	SPI_Write_Buf();

	// PDU TYPE: 2  non-connectable undirected advertising . tx add:random address
	// set BLT PDU length:adv_data+6 mac adress.
	SpiData[0] = 0x08;
	SpiData[1] = ADV_NONCONN_IND | ADV_TXADD_PUBLIC;
	SpiData[2] = 31 + LEN_BLE_ADDR;
	SpiAddr = ADV_PKT_CFG;
	SpiDataLen = 3;
	SPI_Write_Buf();

#else
	// Structure 1
	SpiData[0] = 2;
	SpiData[1] = BLE_GAP_AD_TYPE_FLAGS;
	SpiData[2] = GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED;
	// Structure 2
	SpiData[3] = 19;
	SpiData[4] = BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA;
	SpiData[5] = 0x9c;
	SpiData[6] = 0x05; // MacroGiga
	SpiData[7] = KeyValue;
	SpiData[8] = AddNum;
	SpiData[9] = 3;
	SpiData[10] = 4;
	SpiData[11] = 5;
	SpiData[12] = 6;
	SpiData[13] = 7;
	SpiData[14] = 8;
	SpiData[15] = 9;
	SpiData[16] = 10;
	SpiData[17] = 11;
	SpiData[18] = 12;
	SpiData[19] = 13;
	SpiData[20] = 14;
	SpiData[21] = 15;
	SpiData[22] = 16;
	// Structure 3
	SpiData[23] = 7;
	SpiData[24] = BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME;
	SpiData[25] = 'M';
	SpiData[26] = 'S';
	SpiData[27] = '2';
	SpiData[28] = '5';
	SpiData[29] = '8';
	SpiData[30] = '3';
	SpiAddr = W_TX_PAYLOAD;
	SpiDataLen = 31;
	SPI_Write_Buf();

	// PDU TYPE: 2  non-connectable undirected advertising . tx add:random address
	// set BLT PDU length:adv_data+6 mac adress.
	SpiData[0] = 0x08;
	SpiData[1] = ADV_NONCONN_IND | ADV_TXADD_PUBLIC;
	SpiData[2] = 31 + LEN_BLE_ADDR;
	SpiAddr = ADV_PKT_CFG;
	SpiDataLen = 3;
	SPI_Write_Buf();
#endif

	SpiData[0] = 0x05;
	SpiAddr = BASEBAND_CFG;
	SPI_Write_Reg(); // SLP_XO=4, STOP=2, WKUP_EN=1

	sys_temp_8bit1 = 0x02;
	Delay_ms(); // unit 512us

	SpiData[0] = 0x01;
	SpiAddr = WAKEUP_NOW;
	SPI_Write_Reg();

	f_sys_ble_en = true;
}
/*******************************************************************************
 * Function    : SRCC_CarrierTest
 * Brief       : 载波测试
 * Parameter   :
 * Returns     :
 * Date        : 2020-04-03 17:14:47
 * Description :
 ******************************************************************************/
#if (RfTest == RfTest_Carrier)
void SRCC_CarrierTest(void)
{
	SpiData[2] = 0x80 | A;
	SpiData[1] = 0xC0;
	SpiData[0] = 0x08;
	SpiAddr = CONT_TEST_MODE;
	SpiDataLen = 0x03;
	SPI_Write_Buf();

	SpiData[0] = 0x10;
	SpiAddr = XO_PD_EN;
	SPI_Write_Reg();

	sys_temp_8bit1 = 0x0b;
	Delay_ms(); // unit 512us

	SpiData[0] = 0x01;
	SpiAddr = WAKEUP_NOW;
	SPI_Write_Reg();
}
#endif
/*******************************************************************************
 * Function    : SRRC_PRBS9Test
 * Brief       : 载波测试
 * Parameter   : chan-通道
 * Returns     :
 * Date        : 2020-04-03 17:14:47
 * Description :
 ******************************************************************************/
#if (RfTest == RfTest_Prbs9)
void PayLoad(void)
{
	PCADD A;
	RET 0x00;
	RET 0xa4;
	RET 0xff;
	RET 0x83;
	RET 0xdf;
	RET 0x17;
	RET 0x32;
	RET 0x09;
	RET 0x4E;
	RET 0xD1;
	RET 0xE7;
	RET 0xCD;
	RET 0x8A;
	RET 0x91;
	RET 0xC6;
	RET 0xD5;
	RET 0xC4;
	RET 0xC4;
	RET 0x40;
	RET 0x21;
	RET 0x18;
	RET 0x4E;
	RET 0x55;
	RET 0x86;
	RET 0xF4;
	RET 0xDC;
	RET 0x8A;
	RET 0x15;
	RET 0xA7;
	RET 0xEC;
	RET 0x92;
	RET 0xDF;
	RET 0x93;
	RET 0x53;
	RET 0x30;
	RET 0x18;
	RET 0xCA;
	RET 0x34;
	RET 0xBF;
	RET 0xe2;
	RET 0x21;
	RET 0xe8;
}
void SRRC_PRBS9Test(void)
{
	SpiData[0] = 0x08;
	SpiData[1] = 0x00;
	SpiAddr = PA_CFG;
	SpiDataLen = 0x02;
	SPI_Write_Buf();

	sys_temp_8bit1 = 0x65;
	Delay_ms(); // unit 512us
	SpiData[0] = 0x00;
	SpiAddr = XO_PD_EN;
	SPI_Write_Reg();
	sys_temp_8bit1 = 0x65;
	Delay_ms(); // unit 512us

	SpiAddr = CONT_TEST_MODE;
	SpiDataLen = 3;
	SPI_Read_Buf();
	SpiData[2] &= 0xc0;
	SpiData[2] |= chan;
	SpiData[3] = 0x00;
	SpiData[4] = 0x80;
	SpiAddr = CONT_TEST_MODE;
	SpiDataLen = 0x05;
	SPI_Write_Buf();

	SpiAddr = 0x18;
	SpiDataLen = 0x01;
	SPI_Read_Buf();
	SpiData[0] &= 0xE7;
	SpiData[0] |= 0x18;
	SpiAddr = 0x18;
	SpiDataLen = 0x01;
	SPI_Write_Buf();

	SpiAddr = 0x19;
	SpiDataLen = 0x02;
	SPI_Read_Buf();
	SpiData[2] = 0xf0;
	SpiAddr = 0x19;
	SpiDataLen = 0x03;
	SPI_Write_Buf();

	SpiData[0] = 0x01;
	SpiAddr = WAKEUP_NOW;
	SPI_Write_Reg();

	sys_temp_8bit1 = 0xc8;
	Delay_ms(); // unit 512us
	sys_temp_8bit1 = 0x64;
	Delay_ms(); // unit 512us

	SpiData[0] = 0x08;
	SpiData[1] = 18;
	SpiAddr = PA_CFG;
	SpiDataLen = 0x02;
	SPI_Write_Buf();

	SpiAddr = 0x19;
	SpiDataLen = 0x02;
	SPI_Read_Buf();
	chan = 0;
	while (chan < 42)
	{
		A = chan + 1;
		PayLoad();
		SpiData[2] = A;

		SpiAddr = 0x19;
		SpiDataLen = 0x03;
		SPI_Write_Buf();

		chan++;
	}
}
#endif
/*******************************************************************************
 * Function    : Fun_Ble_Run
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-04-03 17:14:47
 * Description :
 ******************************************************************************/
void Fun_Ble_Run(void)
{
	if (f_sys_ble_standby == true)
	{ //处于低功耗，需要复位芯片，unit-2.048ms
		BleRestDelay++;
		switch (BleRestDelay)
		{
		case 0x01:
			spi_rst = false;
			break;
		case 0x02:
			spi_rst = true;
			break;
		case 0x0f: //复位计时完成
			BLE_Init();
			BLE_Mode_Sleep();
			f_sys_ble_standby = false;
		default:
			break;
		}
		return;
	}

	if (key_status_new != KEY_STATUS_UP)
		BleTxDelay = 0x00; //按键没有松开时一直发码

	if (BleTxDelay < BleTxDelay_SET)
	{ //广播延时计时未达到，继续广播
		if (BleTxDelay != 0x00)
		{
		}

		BleTxDelay++;

		if (f_sys_ble_en == false)
		{ //没有广播，启动广播
			BLE_Tx_Enable();
		}
	}
	else
	{ //广播时间结束
		if (f_sys_ble_en == true)
		{ //处于广播状态，停止广播
			BLE_Mode_Sleep();
			// BLE_Mode_Standby();
		}
	}
}
/*******************************************************************************
 * Function    : Fun_Key_Run
 * Brief       : 按键状态刷新
 * Parameter   :
 * Returns     :
 * Date        : 2020-04-03 17:14:47
 * Description :
 ******************************************************************************/
void Key_Table(void)
{
	PCADD A;
	RET 11111111b; //没有按键按下
	RET 01111111b;
	RET 10111111b;
	RET 11011111b;
	RET 11110111b;
	RET 11101111b;
	RET 11111110b;
}
void Key_Value(void)
{
	PCADD A;
	RET KEY_PA7_PB6;
	RET KEY_PA6_PB6;
	RET KEY_PA5_PB6;
	RET KEY_PA3_PB6;
	RET KEY_PA4_PB6;
	RET KEY_PA0_PB6;
	RET KEY_PA7_PB4;
	RET KEY_PA6_PB4;
	RET KEY_PA5_PB4;
	RET KEY_PA3_PB4;
	RET KEY_PA4_PB4;
	RET KEY_PA0_PB4;
	RET KEY_PA7_PB5;
	RET KEY_PA6_PB5;
	RET KEY_PA5_PB5;
	RET KEY_PA3_PB5;
	RET KEY_PA4_PB5;
	RET KEY_PA0_PB5;
	RET KEY_PA7_PB7;
	RET KEY_PA6_PB7;
	RET KEY_PA5_PB7;
	RET KEY_PA3_PB7;
	RET KEY_PA4_PB7;
	RET KEY_PA0_PB7;
	RET KEY_PA7_GND;
	RET KEY_PA6_GND;
	RET KEY_PA5_GND;
	RET KEY_PA3_GND;
	RET KEY_PA4_GND;
	RET KEY_PA0_GND;
}
void Key_Table_Scan(void)
{
	sys_temp_8bit1 = PA | KEY_READ;
	sys_temp_8bit2 = 0x00;
	while (sys_temp_8bit2 < 7)
	{ //查询该组那个按键按下
		A = sys_temp_8bit2 + 1;
		Key_Table();
		if (sys_temp_8bit1 == A)
			break;

		sys_temp_8bit2++;
	}
	// sys_temp_8bit2，同一组内第几个按键按下

	if (sys_temp_8bit2 > 6)
	{								  //同一组内有多个按键按下
		key_status = KEY_STATUS_ELES; //多按键按下
		sys_temp_8bit2 = 0x00;
	}
	else if (sys_temp_8bit2 != 0)
	{ //有1个按键按下
		if (key_status == 0x00)
			key_status = sys_temp_8bit2;
		else if (key_status > 24)
		{ //对GND有触发
			sys_temp_8bit2 = 0x00;
		}
		else
		{ //排除对GND的按键判断
			key_status = KEY_STATUS_ELES;
			sys_temp_8bit2 = 0x00;
		}
	}
	// else //(sys_temp_8bit2 == 0)
	// {//这一组没有按键按下
	// 	key_status = key_status;
	// }

	//返回，0~6,0xff
}
void Key_Status_Init(void)
{
	PBC &= 00001111b;  // 0-输入，1-输出，全为输入状态,查询对GND按键
	PBPH |= 11110000b; // 上拉，0-无上拉，1-有上拉
}
void Key_Status_Sleep(void)
{
	PBC |= 11110000b; // 0-输入，1-输出，全为输入状态,查询对GND按键
	PB &= 00001111b;
	PBPH &= 00001111b; // 上拉，0-无上拉，1-有上拉
}
void Fun_Key_Scan(void)
{
	// key_status,当前按键按下状态,0~30,0xff

	if (key_status == key_status_new)
	{
		key_delay = 0x00;
	}
	else
	{				 //状态改变
		key_delay++; //按键去抖
		Sleep_Delay_Init();
	}

	if (key_status == KEY_STATUS_UP)
		sys_temp_8bit1 = KEY_DELAY_SHORT_HSET; //松开去抖
	else
		sys_temp_8bit1 = KEY_DELAY_SHORT_LSET; //按下去抖

	if (key_delay >= sys_temp_8bit1)
	{ //按键状态改变
		key_delay = 0x00;
		key_Ldelay = 0x00;
		key_status_old = key_status_now;
		key_status_now = key_status_new;
		key_status_new = key_status;

		if (key_status_new == KEY_STATUS_ELES)
		{ //错误按键
			return;
		}
		else if (key_status_new == KEY_STATUS_UP)
		{ //按键松开
			A = key_status_now;
			Key_Value();
			KeyValue = A;
			key_flag = KEY_FLAG_UP;

			BleTxDelay = 0x00;
			if (f_sys_ble_en == true)
			{ //在发广播，更新数据
				BLE_Stop_Adv();
			}
		}
		else if (key_status_now == KEY_STATUS_UP)
		{ //之前为按键松开状态
#if (RfTest != RfTest_Disable)
			KeyValue++;
			if (KeyValue >= 40)
				KeyValue = 0;

			BLE_RESET();
			BLE_Init();
			chan = KeyValue;
#endif

#if (RfTest == RfTest_Carrier)
			SRCC_CarrierTest();
#elif (RfTest == RfTest_Prbs9)
			SRRC_PRBS9Test();
#else
			A = key_status_new;
			Key_Value();
			KeyValue = A;
			AddNum++; //序列号

			key_times ^= 0x80;

			if (key_status_new == key_status_old)
			{ //连按
				key_times++;
			}
			else
				key_times = 0x01; //第一次按下

			key_flag = KEY_FLAG_DOWN;

			BleTxDelay = 0x00;
			if (f_sys_ble_en == true)
			{ //在发广播，更新数据
				BLE_Stop_Adv();
			}
#endif
		}
		else
		{ //其他状态
			return;
		}
	}

	if (key_Ldelay > KEY_DELAY_LONG_SET)
		return;
	key_Ldelay++;

	if (key_Ldelay == KEY_DELAY_LONG_SET)
	{ //长按

		if (key_status_now == KEY_STATUS_UP)
		{ //之前为按键松开状态
			A = key_status_new;
			Key_Value();
			KeyValue = A;

			key_flag = KEY_FLAG_LONG;

			BleTxDelay = 0x00;
			if (f_sys_ble_en == true)
			{ //在发广播，更新数据
				BLE_Stop_Adv();
			}
		}
	}
	else if (key_Ldelay == KEY_DELAY_TIMES_SET)
	{ //连按判断
		if (key_status_new == KEY_STATUS_UP)
			key_times &= 0x80; //按键松开
	}
}
void Key_Run(void)
{
	ver++;
	switch (ver) //复用版本号
	{
	case 0x01:
		Key_Table_Scan();
		if (sys_temp_8bit2 != 0x00)
			key_status += 24;

		Key_Status_Init();
		PBC |= 10000000b; // PB7输出
		key_Out04_bit = false;
		break;
	case 0x02:
		Key_Table_Scan();
		if (sys_temp_8bit2 != 0x00)
			key_status += 18;

		Key_Status_Init();
		PBC |= 00100000b; // PB5输出
		key_Out03_bit = false;
		break;
	case 0x03:
		Key_Table_Scan();
		if (sys_temp_8bit2 != 0x00)
			key_status += 12;

		Key_Status_Init();
		PBC |= 00010000b; // PB4输出
		key_Out02_bit = false;
		break;
	case 0x04:
		Key_Table_Scan();
		if (sys_temp_8bit2 != 0x00)
			key_status += 6;

		Key_Status_Init();
		PBC |= 01000000b; // PB6输出
		key_Out01_bit = false;
		break;
	case 0x05:
		Key_Table_Scan();
		// if (sys_temp_8bit2 != 0x00)
		// 	key_status += 0;

		Key_Status_Init();
		// PBC |= 00000000b; // 输出
		// key_Out05_bit = false;
		//灯扫描
#if (LED_SUPPORT == true)
		if (f_sys_ble_en == true)
		{
			PAC |= 00100000b; // 0-输入，1-输出
			led_bit = false;
		}
#endif
		Fun_Key_Scan();
		break;
	default:
		ver = 0x00;
		// LED(PA5)
		PA |= 11111001b;
		Delay_Nop();
		PAC &= 11011111b; // 0-输入，1-输出

		Key_Status_Init();
		// PBC |= 00000000b; // 输出
		// key_Out05_bit = false;

		key_status = 0x00;
		break;
	}
}
/*******************************************************************************
 * Function    : Fun_Io_Init
 * Brief       : 初始化
 * Parameter   :
 * Returns     :
 * Date        : 2020-04-03 17:14:47
 * Description :
 ******************************************************************************/
void Fun_Io_Init(void)
{
	.DISGINT;					// 全局中断关闭
	.CLKMD.En_WatchDog = false; // 关闭看门狗时钟
	INTEN = 0x00;
	INTRQ = 0x00;

	// IO设置
	PA = 00000000b;		// 状态
	PAC = 00000000b;	// 输入输出控制，0-输入，1-输出
	PAPH = 11111111b;	// 上拉，0-无上拉，1-有上拉
	$ PADIER 11111001b; // 1-启用唤醒，0-禁用唤醒,做输入时必须是1

	PB = 00001100b;
	PBC = 00001111b;	// 输入输出控制，0-输入，1-输出
	PBPH = 11110000b;	// 上拉，0-无上拉，1-有上拉
	$ PBDIER 00001111b; // 1-启用唤醒，0-禁用唤醒,做输入时必须是1
}
/*******************************************************************************
 * Function    : Fun_Mcu_Init
 * Brief       : 初始化
 * Parameter   :
 * Returns     :
 * Date        : 2020-04-03 17:14:47
 * Description :
 ******************************************************************************/
void Fun_Mcu_Init(void)
{
	MISC = 0x00; //看门狗时间设定，低电压复位使能

	$ T16M SYSCLK, / 1, BIT8; //定时时间 = 2^(BIT?+1)/SYSCLK*分频
	//$ T16M STOP;                  // 停止

	.CLKMD.En_Reset = false; //不使能复位脚

	EOSCR = 0x00;  //外部晶振与低电压复位（默认，无须更改）
	INTEGS = 0x00; // T16/PB0/PA4/PB5/PA0的中断方式

	/*
	//T2,频率=时钟/(256*预分频*(分频+1))*2
	$ TM2C IHRC, PA3, PWM, ;        //时钟源，输出脚，输出模式，高或低输出
	$ TM2S 8bit, /1, /1;            //精度，预分频，分频
	TM2CT = 0x00;                   //计算器
	TM2B = 0x32;                    //占空比
	*/

	//比较控制寄存器
	GPCC = 0x00; //比较控制寄存器
	GPCS = 0x00;

	//计时器中断使能
	INTRQ = 0x00;
	INTEN.T16 = true; //中断使能
	ENGINT;			  // 全局中断使能
}
/*******************************************************************************
 * Function    : Fun_Data_Init
 * Brief       : 数据初始化
 * Parameter   :
 * Returns     :
 * Date        : 2020-04-03 17:14:47
 * Description :
 ******************************************************************************/
void Fun_Clr_RAM(void)
{
	//清除所有RAM,注意系统调用占用的空间，防止无限重启
	point = _SYS(RAM_SIZE) - 0x1a;
	do
	{
		*point = 0x00;
		point $ 0 --;
	} while (point$0 != 0x00);
}
//------------------------------------------------------------------------------
void Fun_Data_Init(void)
{
	Fun_Clr_RAM();
	Fun_Clr_RAM(); //清两次是当延时函数用，上电延时

	// CALL _SYS(ADR.ROLL); //滚码
	// device_address1 = A;
	// CALL _SYS(ADR.ROLL) + 1;
	// device_address2 = A;
	// CALL _SYS(ADR.ROLL) + 2;
	// device_address3 = A;

	//下面设定初始值非0x00的寄存器
}
/*******************************************************************************
 * Function    : Fun_Sleep_Scan
 * Brief       : 数据初始化
 * Parameter   :
 * Returns     :
 * Date        : 2020-04-03 17:14:47
 * Description :
 ******************************************************************************/
void Sleep_Delay_Init(void)
{
	sys_sleep_delay = 0x00;
}
void Fun_Sleep_Scan(void)
{
	if (f_sys_ble_en == true)
		Sleep_Delay_Init(); //蓝牙在工作
	if (key_status_new != KEY_STATUS_UP)
		Sleep_Delay_Init(); //按键没有松开
	// else if (key_Ldelay < KEY_DELAY_TIMES_SET)
	// 	Sleep_Delay_Init();//

	sys_sleep_delay++;
	if (sys_sleep_delay < sys_sleep_delay_set)
		return;
	sys_sleep_delay = 0x00;

	Key_Status_Sleep(); //按键休眠准备
	BLE_Mode_Standby(); //蓝牙进入standby模式，功耗更低

	//进入休眠
	INTEN.T16 = false;
	INTRQ = 0x00;				// 清除中断旗标
	.CLKMD = 0xf4;				//切换为低频时钟
	.CLKMD.En_WatchDog = false; // 关闭看门狗时钟

	Delay_Nop();
	STOPSYS;
	Delay_Nop();

	.Wdreset;
	.CLKMD = 0x14 | 0x08;	   // IRC,1M
	.CLKMD.En_WatchDog = true; // 开启看门狗时钟
	INTEN.T16 = true;
	INTRQ = 0x00; // 清除中断旗标
}
/*******************************************************************************
 * Function    : main
 * Brief       : 主函数
 * Parameter   :
 * Returns     :
 * Date        : 2020-04-03 17:14:47
 * Description :
 ******************************************************************************/
void FPPA0(void)
{
	.ADJUST_IC SYSCLK = IHRC/ 16, IHRC = 16MHz, VDD = 3.3V; // SYSCLK=IHRC/2

	//	Insert Initial Code
	Fun_Io_Init();
	Fun_Data_Init();
	Fun_Mcu_Init();

	//上电延时100ms
	sys_temp_8bit1 = 0xc3;
	Delay_ms(); // unit 512us

	BLE_RESET();
	BLE_Init();
	while (1)
	{
		if (f_sys_2ms == true)
		{ // 2.048MS
			f_sys_2ms = false;

			Key_Run();
			Fun_Ble_Run();
			Fun_Sleep_Scan();
		}
		.Wdreset;
	}
}
/*******************************************************************************
 * Function    : Interrupt
 * Brief       : 中断
 * Parameter   :
 * Returns     :
 * Date        : 2020-04-03 17:14:47
 * Description :
 ******************************************************************************/
void Interrupt(void)
{
	pushaf;

	if (Intrq.T16)
	{ //	T16 Trig
		Intrq.T16 = false;
		f_sys_tmr = true;
		sys_delay++;
		if (sys_delay >= sys_delay_set)
		{
			sys_delay = 0x00;
			f_sys_2ms = true;
		}
	}

	popaf;
}
